/*
 * 投中信息
 * Copyright 2017 (C) All Rights Reserved.
 */
package cn.studyjava.verify.code12306.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.studyjava.verify.code12306.model.GroupParams;
import cn.studyjava.verify.code12306.model.GroupSingleton;
import cn.studyjava.verify.code12306.model.ImageParam;

/**
 * <p>
 * Description:
 * </p>
 * 
 * @author: zsljava
 * @version 1.0.0
 * <p>
 * History:
 * -----------------------------------------------
 * @Date: 2017年9月6日 上午11:00:09
 * @author: zsljava
 * @version 1.0.0
 * @OP: Create
 * -----------------------------------------------
 * </p>
 *
 * @since
 * @see
 */
public class FileUtil {
	private static Logger log = LoggerFactory.getLogger(FileUtil.class);
	
	private static Map<String, List<ImageParam>> map = new ConcurrentHashMap<String, List<ImageParam>>();
	
	private static ThreadPoolExecutorUtil threadPoolExecutorUtil = new ThreadPoolExecutorUtil();
	
	/**
	 * 记录当前图片加载的数量
	 */
	private static AtomicInteger count = new AtomicInteger(0);
	/**
	 * 
	 * @Title: singleThreadReadFile
	 * @Description: 单线程 读取某个文件夹下的所有文件
	 * @param path
	 * @return: void
	 */
	public static void singleThreadReadFile(String path) { 
		log.debug("加载图片 路径 {}", path);
		FileInputStream inputStream = null;
		ByteArrayOutputStream outStream = null;
    	try{
	    	Map<String, List<ImageParam>> map = new HashMap<String, List<ImageParam>>();
	        File file = new File(path);  
	        if (file.isDirectory()) {  
	            File[] dirFile = file.listFiles();  
	            for (File f : dirFile) {  
	                if (f.isDirectory())  
	                	singleThreadReadFile(f.getAbsolutePath());  
	                else {  
	                	int len = 0;
						inputStream = new FileInputStream(f);
						outStream = new ByteArrayOutputStream();
						byte[] buffer = new byte[1024];
						while ((len = inputStream.read(buffer)) != -1) {
							outStream.write(buffer, 0, len);
						}
						String data = Base64Util.encodeImg(outStream.toByteArray());
						String str = f.getName();
						String[] arr = str.split("_");
						String name = arr[0];
						List<ImageParam> sp = null;
						if (map.containsKey(name)) {
							sp = (List<ImageParam>) map.get(name);
						} else {
							sp = new ArrayList<ImageParam>();
						}
						sp.add(new ImageParam(name, data));
						map.put(name, sp);
	                }  
	            }  
	        }  
	        Iterator<Entry<String, List<ImageParam>>> it = map.entrySet()
					.iterator();
			while (it.hasNext()) {
				Entry<String, List<ImageParam>> entry = it.next();
				GroupSingleton.getInstance().add(new GroupParams(entry.getKey(), entry.getValue()));
			}
    	}catch(Exception e){
    		e.printStackTrace();
    		log.error("加载验证图   Exception:{}", e.getMessage());
    	}finally {
    		try {
				if(null != outStream){
					outStream.close();
				}
				if(null != inputStream){
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    }  
	
	
	/**
	 * 
	 * @Title: multiThreadReadFile
	 * @Description: 多线程 读取某个文件夹下的所有文件
	 * @param path
	 * @return: void
	 */
	public static void multiThreadReadFile(String path) {
		log.debug("加载图片 路径 {}", path);
		try {
			File file = new File(path);
			if(!file.exists()){
				file.mkdirs();
			}
			if (file.isDirectory()) {
				if(file.listFiles().length == 0){
					String dir = FileUtil.class.getResource("/").getPath();
					copyFolder(new File(dir.concat("defverify")), file);
				}
				File[] dirFile = file.listFiles();
				for (File f : dirFile) {
					if (f.isDirectory())
						multiThreadReadFile(f.getAbsolutePath());
					else {
						threadPoolExecutorUtil.execute(() -> {
							read(f);
						});
					}
				}
			}
			threadPoolExecutorUtil.finish();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
		
		Iterator<Entry<String, List<ImageParam>>> it = map.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, List<ImageParam>> entry = it.next();
			GroupSingleton.getInstance().add(new GroupParams(entry.getKey(), entry.getValue()));
		}
		log.info("验证码共 {} 种", GroupSingleton.getInstance().size());
	}

	/**
	 * @Title: read
	 * @Description: TODO
	 * @param f
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @return: void
	 */
	private static void read(File f) {
//		ThreadPoolExecutor theadPool = (ThreadPoolExecutor)executorService;
//		int threadCount = theadPool.getActiveCount();
//		int queueCount = theadPool.getQueue().size();
		log.debug("加载图片 {}, 当前线程数量 {}, 当前Queue数量 {} ", f.getName(), threadPoolExecutorUtil.getActiveCount(), threadPoolExecutorUtil.getQueue().size());
		int len = 0;
		FileInputStream inputStream = null;
		ByteArrayOutputStream outStream = null;
		try {
			inputStream = new FileInputStream(f);
			outStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			while ((len = inputStream.read(buffer)) != -1) {
				outStream.write(buffer, 0, len);
			}
			String data = Base64Util.encodeImg(outStream.toByteArray());
			String str = f.getName();
			String[] arr = str.split("_");
			String name = arr[0];
			List<ImageParam> sp = null;
			if (map.containsKey(name)) {
				sp = (List<ImageParam>) map.get(name);
			} else {
				sp = new ArrayList<ImageParam>();
			}
			sp.add(new ImageParam(name, data));
			map.put(name, sp);
			count.incrementAndGet();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("读取验证图   Exception:{}", e.getMessage());
		}finally {
			try {
				if(null != outStream){
					outStream.close();
				}
				if(null != inputStream){
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/** 
	 * 复制一个目录及其子目录、文件到另外一个目录 
	 * @param src 
	 * @param dest 
	 * @throws IOException 
	 */  
	public static void copyFolder(File src, File dest) throws IOException {  
	    if (src.isDirectory()) {  
	        if (!dest.exists()) {  
	            dest.mkdir();  
	        }  
	        String[] files = src.list();  
	        for (String file : files) {  
	            File srcFile = new File(src, file);  
	            File destFile = new File(dest, file);  
	            // 递归复制  
	            copyFolder(srcFile, destFile);  
	        }  
	    } else {  
	        InputStream in = new FileInputStream(src);  
	        OutputStream out = new FileOutputStream(dest);  
	  
	        byte[] buffer = new byte[1024];  
	  
	        int length;  
	          
	        while ((length = in.read(buffer)) > 0) {  
	            out.write(buffer, 0, length);  
	        }  
	        out.close();  
	        in.close();  
	    }  
	}  
}
